|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 00016 #include "derivative.h" 00017 #include "Compile_Options.h" 00018 #include "Decision.h" 00019 #include "SM.h" 00020 #include "SBC_AL.h" 00021 #include "HAL.h" 00022 #include "MailScheduler.h" 00023 #include "Application_Globals.h" 00024 #include "SIU.h" 00025 /* 00026 ****************************************************************************** 00027 * Constants 00028 ****************************************************************************** 00029 */ 00031 const uint16_t cau16PreDecisionValidStates[] = 00032 { 00033 SM_STATE_ERROR, SM_APPLICATION_START }; 00034 /* 00035 ****************************************************************************** 00036 * Globals 00037 ****************************************************************************** 00038 */ 00039 /* 00040 ****************************************************************************** 00041 * u32fnStateDecision 00042 ****************************************************************************** 00043 */ 00044 uint32_t u32fnStateDecision(void) 00045 { 00046 uint32_t u32Status; 00047 00048 00049 /* Verify that we can execute - Previous state ended correctly */ 00050 u32Status 00051 = u32fnSMValidateCurrentState((uint16_t*)cau16PreDecisionValidStates, 00052 N_ELEMENTS(cau16PreDecisionValidStates)); 00053 if(CLEAR == u32Status) 00054 { 00055 /* Here comes the real contents of the state */ 00056 LOCK_STATE_EXECUTION(); 00057 00058 /* Run the algorithm */ 00059 u32Status = u32fnDecisionMath(gu16ActivePSI5Channels, 00060 (uint16_t*)&gau16RawAccels[SM_PSI5_GLOBAL_INDEX], 00061 (uint16_t*)&gu16CrashedSatellites); 00062 if(CLEAR == u32Status) 00063 { 00064 /* Run the Safing */ 00065 u32Status = u32fnDecisionSafing(gu16CrashedSatellites, 00066 (uint16_t*)&gau16RawAccels[SM_CA_GLOBAL_INDEX], 00067 (uint16_t*)&gu16ConfirmedSatellites); 00068 00069 /* Result from operation above will flag confirmed satellites only; */ 00070 /* meaning that if the error flag is set, it is due to an unconfirmed */ 00071 /* satellite. Therefore, we must treat this error accordingly, but we */ 00072 /* shall also decide which squibs are going to be triggered. Therefore */ 00073 /* the next step does not require an empty u32Status, but it will */ 00074 /* remember the previous one and report it. */ 00075 u32Status |= u32fnDecisionSelection(gu16ConfirmedSatellites, 00076 gu16ActiveSquibChannels, 00077 (uint16_t*)&gu16SquibsToFire); 00078 } 00079 else 00080 { 00081 /* Leave with error code */ 00082 } 00083 /* Unlock the state */ 00084 UNLOCK_STATE_EXECUTION(); 00085 } 00086 else 00087 { 00088 /* Leave */ 00089 } 00090 00091 /* Set the next state */ 00092 if(CLEAR == u32Status) 00093 { 00094 vfnSMWriteNextState(SM_STATE_DEPLOYMENT); 00095 } 00096 else 00097 { 00098 vfnSMWriteNextState(SM_STATE_ERROR); 00099 } 00100 return (u32Status); 00101 } 00102 /* 00103 ****************************************************************************** 00104 * u32fnDecisionMath 00105 ****************************************************************************** 00106 */ 00107 static uint32_t u32fnDecisionMath(const uint16_t cu16PSI5Channels, 00108 const uint16_t* pu16Acceleration, 00109 uint16_t* pu16SatelliteSensedCrash) 00110 { 00111 uint32_t u32Status; 00112 uint8_t u8Index; 00113 uint16_t u16ChannelMask; 00114 00115 u32Status = CLEAR; 00116 u8Index = CLEAR; 00117 00118 /* Below is a sample application where satellite sensors are compared */ 00119 /* against a threshold; if the threshold is passed, we assume there has */ 00120 /* been an impact detected by the sensor. Real world application should */ 00121 /* replace this threshold detection since it is not tested in any kind */ 00122 /* of environment other than a lab with an evaluation board and is not */ 00123 /* representative of a complete solution. */ 00124 *pu16SatelliteSensedCrash = CLEAR; 00125 for(u16ChannelMask = BIT0; u16ChannelMask < BIT12; u16ChannelMask <<= 1u) 00126 { 00127 if(u16ChannelMask & cu16PSI5Channels) 00128 { 00129 /* If the channel is active, check the acceleration vs. the threshold */ 00130 *pu16SatelliteSensedCrash |= 00131 (*(pu16Acceleration + u8Index) > cau16PSI5CrashThresholds[u8Index]) 00132 << u8Index; 00133 } 00134 else 00135 { 00136 /* Not going to perform a test against this */ 00137 } 00138 u8Index++; 00139 } 00140 return(u32Status); 00141 } 00142 /* 00143 ****************************************************************************** 00144 * u32fnDecisionSafing 00145 ****************************************************************************** 00146 */ 00147 static uint32_t u32fnDecisionSafing(const uint16_t cu16CrashedSatellites, 00148 const uint16_t* pu16CAAccel, 00149 uint16_t* pu16ConfirmedSatellites) 00150 { 00151 uint32_t u32Status; 00152 uint8_t au8CAShock[2u]; 00153 uint8_t u8Index; 00154 uint16_t u16ChannelMask; 00155 00156 /* Init variables */ 00157 u8Index = CLEAR; 00158 *pu16ConfirmedSatellites = CLEAR; 00159 u32Status = CLEAR; 00160 00161 /* We will now consult our central accelerometer with regards to the crash */ 00162 /* A "1" will be set if there has been a crash, "0" otherwise. */ 00163 au8CAShock[CA_CRASH_X] = (*pu16CAAccel > cau16CACrashThresholds[CA_CRASH_X]); 00164 au8CAShock[CA_CRASH_Y] = (*(pu16CAAccel + 1u) > 00165 cau16CACrashThresholds[CA_CRASH_Y]); 00166 00167 /* Next, we will go through all satellites */ 00168 for(u16ChannelMask = BIT0; u16ChannelMask < BIT12; u16ChannelMask <<= 1u) 00169 { 00170 if(cu16CrashedSatellites & u16ChannelMask) 00171 { 00172 /* This satellite has detected a crash condition. Check it against */ 00173 /* it's safing axis which is correlated through a special table */ 00174 if(TRUE == au8CAShock[cau8SatelliteDetectionDirection[u8Index]]) 00175 { 00176 /* CA has detected a shock in the pertinent direction */ 00177 /* we agree with it, therefore we can continue checking DIS_ALP and DIS_AHP*/ 00178 if((CLEAR == u8fnReadPin(PIN_DIS_ALP)) && (CLEAR == u8fnReadPin(PIN_DIS_AHP))) 00179 { 00180 /* Add to the list of confirmed satellites */ 00181 *pu16ConfirmedSatellites |= u16ChannelMask; 00182 }/* end if safing is confirmed */ 00183 else 00184 { 00185 /* Safing has not been confirmed. We need to flag this in the */ 00186 /* status word */ 00187 u32Status |= DECISION_ERROR_SAFING_PIN; 00188 } /* end else (safing is not confirmed) */ 00189 } /* end if CA confirms acceleration axis */ 00190 else 00191 { 00192 /* The accelerometer did not agree with the satellite. */ 00193 /* This is not an error, just a working condition. */ 00194 /* We will not flag it */ 00195 /* u32Status |= CLEAR; */ 00196 } /* end else (CA does not confirm acceleration axis) */ 00197 } /* end if satellite has been detected as crashed */ 00198 else 00199 { 00200 /* This satellite has not been crashed */ 00201 } 00202 u8Index++; 00203 } 00204 return(u32Status); 00205 } 00206 /* 00207 ****************************************************************************** 00208 * u32fnDecisionSelection 00209 ****************************************************************************** 00210 */ 00211 static uint32_t u32fnDecisionSelection(const uint16_t cu16ConfirmedSatellites, 00212 const uint16_t cu16ActiveSquibs, 00213 uint16_t* pu16SquibsToFire) 00214 { 00215 uint32_t u32Status; 00216 uint8_t u8Index1; 00217 uint8_t u8Index2; 00218 uint16_t u16ChannelMask; 00219 00220 u32Status = CLEAR; 00221 00222 /* Index1 will tell us which satellite we're referring to */ 00223 u8Index1 = CLEAR; 00224 00225 /* Forget any previous firing values */ 00226 *pu16SquibsToFire = CLEAR; 00227 00228 for(u16ChannelMask = BIT0; u16ChannelMask < BIT12; u16ChannelMask <<= 1u) 00229 { 00230 if(u16ChannelMask & cu16ConfirmedSatellites) 00231 { 00232 /* If this is a confirmed satellite, we need to fire all squibs */ 00233 /* related to it Index2 keeps record of where in the relationship */ 00234 /* table between satellites and squibs we are. */ 00235 for(u8Index2 = CLEAR; u8Index2 < cu8SizeOfSatToSquibs; u8Index2 += 2u) 00236 { 00237 /* We will search the whole table */ 00238 if(cau8SatToSquibs[u8Index2] == u8Index1) 00239 { 00240 /* And if there's a match, we will verify that this is an active */ 00241 /* squib - we never want to enable an inactive squib. */ 00242 if(cu16ActiveSquibs & (BIT0 << cau8SatToSquibs[(u8Index2 + 1u)])) 00243 { 00244 /* If this is the satellite in question, enable the squib if */ 00245 *pu16SquibsToFire |= (BIT0 << cau8SatToSquibs[(u8Index2 + 1u)]); 00246 } 00247 else 00248 { 00249 /* This is an inactive squib, we can't do anything about it */ 00250 } 00251 } 00252 else 00253 { 00254 /* There's nothing to do */ 00255 } 00256 } /* End for */ 00257 } /* end if squib is active */ 00258 else 00259 { 00260 /* Don't fire anything */ 00261 } /* end else (squib is not active) */ 00262 u8Index1++; 00263 }/* end for */ 00264 00265 return(u32Status); 00266 } 00267 /* 00268 ****************************************************************************** 00269 * 00270 * End of file. 00271 * 00272 ****************************************************************************** 00273 */